package com.huluobo.a2111douyindemo.view;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Point;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.animation.AccelerateInterpolator;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import androidx.annotation.NonNull;

/**
 * Created by LC on 2024/3/11.
 * 贝塞尔曲线 带动画 飘心View
 * 1.创建鉴别器,生成贝塞尔曲线的移动轨迹
 * 2.ImageView添加到布局上
 * 3.添加动画,给动画添加贝塞尔曲线的轨迹
 */
public class BezierLineAnimView extends RelativeLayout {

    private int[] resId;

    public void setResId(int[] resId) {
        this.resId = resId;
    }

    public BezierLineAnimView(Context context) {
        super(context);
    }

    public BezierLineAnimView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    //添加心的方法
    public void addFavor() {
        //1.创建出一个ImageView,添加到当前布局上
        ImageView animView = new ImageView(getContext());
        int index = (int) (Math.random() * resId.length);//生成一个随机数的下标,用于控制心的背景颜色
        animView.setImageResource(resId[index]);

        LayoutParams params = new LayoutParams(200, 200);
        animView.setLayoutParams(params);
        addView(animView);//添加imageView到布局上

        //2.定义起始点和控制点
        int width = getMeasuredWidth();//拿到当前Layout的宽高
        int height = getMeasuredHeight();
        float offset = 100;//当前ImageView一半的大小

        //定义起始坐标点
        PointF P0 = new PointF(width / 2.0f - offset, height);//起点
        PointF P3 = new PointF(width / 2.0f - offset, 0);//终点

        //定义控制点
        PointF P1 = new PointF((float) (Math.random() * width) - offset, height / 3.0f * 2 - offset);
        PointF P2 = new PointF((float) (Math.random() * width) - offset, height / 3.0f - offset);

        //3.定义属性动画
        ValueAnimator animator = ValueAnimator.ofObject(new BezierTypeEvaluator(P1, P2), P0, P3);
        animator.setDuration(1200);
        animator.setInterpolator(new AccelerateInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(@NonNull ValueAnimator animation) {
                PointF pointF = (PointF) animation.getAnimatedValue();
                animView.setX(pointF.x);
                animView.setY(pointF.y);
                float f = animator.getAnimatedFraction();
                animView.setAlpha(1 - f);
            }
        });

        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                removeView(animView);
            }
        });

        animator.start();


    }

    //贝塞尔曲线的鉴别器 相当于一个公式(曲线公式)
    class BezierTypeEvaluator implements TypeEvaluator<PointF> {
        PointF P1, P2;//代表曲线拉伸的点

        public BezierTypeEvaluator(PointF p1, PointF p2) {
            P1 = p1;
            P2 = p2;
        }

        @Override
        public PointF evaluate(float f, PointF P0, PointF P3) {
            PointF P = new PointF();
            //三阶贝塞尔曲线移动公式
            //计算x轴
            P.x = P0.x * (1 - f) * (1 - f) * (1 - f)
                    + 3 * P1.x * f * (1 - f) * (1 - f)
                    + 3 * P2.x * f * f * (1 - f)
                    + P3.x * f * f * f;

            P.y = P0.y * (1 - f) * (1 - f) * (1 - f)
                    + 3 * P1.y * f * (1 - f) * (1 - f)
                    + 3 * P2.y * f * f * (1 - f)
                    + P3.y * f * f * f;

//            //四阶贝塞尔曲线x点的移动轨迹
//            P.x = P0.x * (1 - f) * (1 - f) * (1 - f) * (1 - f)
//                    + 4 * P1.x * f * (1 - f) * (1 - f) * (1 - f)
//                    + 4 * P2.x * f * f * (1 - f) * (1 - f)
//                    + 4 * P3.x * f * f * f * (1 - f)
//                    + P4.x * f * f * f * f;
//
//            //二阶贝塞尔曲线
//            P.x = P0.x * (1 - f) * (1 - f)
//                    + 2 * P1.x * f * (1 - f)
//                    + 2 * P2.x * f * f;
//
//            //一阶贝塞尔曲线
//            P.x = P0.x * (1 - f)
//                    + 1 * P1.x * f

            return P;
        }
    }
}
